package com.simen.hellobytes.datetime;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * author: SimenHi
 * create time: 2019-12-26 11:48
 * description:
 */
public class DatetimeUtil {

    public static final int UNKNOWN = 0x9999;

    public static boolean isToday(int year, int month, int day) {
        return isToday(TimeZone.getDefault(), year, month, day);
    }

    public static boolean isToday(TimeZone zone, int year, int month, int day) {
        Calendar calendar = Calendar.getInstance(zone);

        return year == calendar.get(Calendar.YEAR)
                && getStandardMonth(month) == calendar.get(Calendar.MONTH)
                && day == calendar.get(Calendar.DAY_OF_MONTH);
    }

    public static String nowTime() {
        return nowTime("yyyy-MM-dd HH:mm:ss");
    }

    public static String nowTime(String format) {
        return formatDate(new Date(), format);
    }

    public static String formatDate(Date date, String format) {
        SimpleDateFormat dateFormat = new SimpleDateFormat();
        return formatDate(dateFormat, date, format);
    }

    public static String formatDate(SimpleDateFormat dateFormat, Date date, String format) {
        dateFormat.applyPattern(format);
        return dateFormat.format(date);
    }

    public static Date parseDate(String dateStr, String format) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat();
        return parseDate(dateFormat, dateStr, format);
    }

    public static Date parseDate(SimpleDateFormat dateFormat, String dateStr, String format) throws ParseException {
        dateFormat.applyPattern(format);
        return dateFormat.parse(dateStr);
    }

    public static Date getToday() {
        Calendar calendar = Calendar.getInstance();
        int year=calendar.get(Calendar.YEAR);
        int month=calendar.get(Calendar.MONTH);
        int day=calendar.get(Calendar.DAY_OF_MONTH);
        calendar.clear();
        calendar.set(year, month, day);
        return calendar.getTime();
    }

    public static Date getDay(int year, int month, int day) {
        return getDay(TimeZone.getDefault(), year, month, day);
    }

    public static Date getDay(TimeZone zone, int year, int month, int day) {
        Calendar calendar = Calendar.getInstance(zone);
        calendar.clear();
        calendar.set(year,
                getStandardMonth(month),
                day);
        return calendar.getTime();
    }

    public static boolean todayIsWeekDay() {
        return isWeekDay(System.currentTimeMillis());
    }

    public static boolean isWeekDay(long millis) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(millis);
        switch (calendar.get(Calendar.DAY_OF_WEEK)) {
            case Calendar.SATURDAY:
            case Calendar.SUNDAY:
                return true;
        }

        return false;
    }

    public static boolean betweenTime(String beginTimeStr, String endTimeStr) {
        return betweenDateTime(new Date(), beginTimeStr, endTimeStr, "HH:mm");
    }

    public static boolean betweenDateTime(Date date, String beginDateTimeStr, String endDateTimeStr, String format) {
        SimpleDateFormat df = new SimpleDateFormat(format);

        Date now = null;
        Date beginTime = null;
        Date endTime = null;

        try {
            now = df.parse(df.format(date));
            beginTime = df.parse(beginDateTimeStr);
            endTime = df.parse(endDateTimeStr);

            if (now.compareTo(beginTime) >= 0 && now.compareTo(endTime) <= 0) {
                return true;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    public static boolean isSameDay(Date date, Date date1) {
        return isSameDay(date.getTime(), date1.getTime());
    }

    public static boolean isSameDay(long millis, long millis1) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(millis);

        int year1 = calendar.get(Calendar.YEAR);
        int month1 = calendar.get(Calendar.MONTH);
        int day1 = calendar.get(Calendar.DAY_OF_MONTH);

        calendar.setTimeInMillis(millis1);

        if (year1 == calendar.get(Calendar.YEAR)
                && month1 == calendar.get(Calendar.MONTH)
                && day1 == calendar.get(Calendar.DAY_OF_MONTH)) {
            return true;
        }

        return false;
    }

    private static String formatWeekDay(int dayOfWeek) {
        switch (dayOfWeek) {
            case Calendar.SUNDAY:
                return "星期日";
            case Calendar.MONDAY:
                return "星期一";
            case Calendar.TUESDAY:
                return "星期二";
            case Calendar.WEDNESDAY:
                return "星期三";
            case Calendar.THURSDAY:
                return "星期四";
            case Calendar.FRIDAY:
                return "星期五";
            case Calendar.SATURDAY:
                return "星期六";
        }
        return "Unknown";
    }

    /**
     * java标准月份转为月份
     */
    public static int getMonth(int standardMonth){
        switch (standardMonth) {
            case Calendar.JANUARY:
                return 1;
            case Calendar.FEBRUARY:
                return 2;
            case Calendar.MARCH:
                return 3;
            case Calendar.APRIL:
                return 4;
            case Calendar.MAY:
                return 5;
            case Calendar.JUNE:
                return 6;
            case Calendar.JULY:
                return 7;
            case Calendar.AUGUST:
                return 8;
            case Calendar.SEPTEMBER:
                return 9;
            case Calendar.OCTOBER:
                return 10;
            case Calendar.NOVEMBER:
                return 11;
            case Calendar.DECEMBER:
                return 12;
            case Calendar.UNDECIMBER:
                return 12;
            default:
                return UNKNOWN;
        }
    }

    /**
     * 月份转为java标准月份
     */
    public static int getStandardMonth(int month) {
        switch (month) {
            case 1:
                return Calendar.JANUARY;
            case 2:
                return Calendar.FEBRUARY;
            case 3:
                return Calendar.MARCH;
            case 4:
                return Calendar.APRIL;
            case 5:
                return Calendar.MAY;
            case 6:
                return Calendar.JUNE;
            case 7:
                return Calendar.JULY;
            case 8:
                return Calendar.AUGUST;
            case 9:
                return Calendar.SEPTEMBER;
            case 10:
                return Calendar.OCTOBER;
            case 11:
                return Calendar.NOVEMBER;
            case 12:
                return Calendar.DECEMBER;
            default:
                return UNKNOWN;
        }
    }

    private static final long SECOND = 1000;
    private static final long MINUTE = SECOND * 60;
    private static final long HOUR = MINUTE * 60;
    private static final long DAY = HOUR * 24;
    private static final long WEEK = DAY * 7;

    public static String durationString(long millis) {
        if (millis == -1) {
            return "";
        }

        if (millis < SECOND) {
            return millis + "毫秒";
        } else if (millis < MINUTE) {
            return millis / SECOND + "秒" + durationString(millis % SECOND != 0 ? (millis % SECOND) : -1);
        } else if (millis < HOUR) {
            return millis / MINUTE + "分钟" + durationString(millis % MINUTE != 0 ? (millis % MINUTE) : -1);
        } else if (millis < DAY) {
            return millis / HOUR + "小时" + durationString(millis % HOUR != 0 ? (millis % HOUR) : -1);
//        } else if (millis < WEEK) {
//            return millis / DAY + "天";
//        } else {
//            return millis / WEEK + "周";
        } else {
            return millis / DAY + "天" + durationString(millis % DAY != 0 ? (millis % DAY) : -1);
        }
    }
}
